import * as THREE from 'three'
import * as TWEEN from '@tweenjs/tween.js'
import { loadFBX } from '../utils'
import { BackGround } from '../effect/background'
import { SurroundLine } from '../effect/surroundLine'
import { Radar } from '../effect/radar'
import { Wall } from '../effect/wall'
import { Circle } from '../effect/circle'
import { Ball } from '../effect/ball'
import { Cone } from '../effect/cone'
import { Fly } from '../effect/fly'
import { Road } from '../effect/road'
import { Font } from '../effect/font'
import { Snow } from '../effect/snow'
import { Rain } from '../effect/rain'
import { Smoke } from '../effect/smoke'
export class City {
  constructor(scene, camera, controls) {
    this.controls = controls
    this.scene = scene
    this.camera = camera
    this.tweenPosition = null
    this.tweenRotation = null
    this.flag = false
    this.height = {
      value: 5
    }
    this.time = {
      value: 0
    }
    this.top = {
      value: 0
    }
    this.effect = {}
    this.loadCity()
  }
  async loadCity() {
    // 加载模型 并渲染到画布上
    const obj = await loadFBX('src/model/beijing.fbx')
    obj.traverse((child) => {
      if (child.isMesh) {
        new SurroundLine(this.scene, child, this.height, this.time)
      }
    })
    this.initEffect()
  }

  initEffect() {
    // 添加天空背景
    // new BackGround(this.scene)
    // // 雷达效果
    // new Radar(this.scene, this.time)
    // // 透明墙
    // new Wall(this.scene, this.time)
    // // 扩散圆
    // new Circle(this.scene, this.time)
    // // 半球体
    // new Ball(this.scene, this.time)
    // // 旋转四棱锥
    // new Cone(this.scene, this.top, this.height)
    // // 飞线
    // new Fly(this.scene, this.time)
    // // 路径移动
    // new Road(this.scene, this.time)
    // // 场景文字
    // new Font(this.scene)
    // 雪花
    // this.effect.snow = new Snow(this.scene)
    // 下雨
    // this.effect.rain = new Rain(this.scene)
    // 烟雾预警
    this.effect.smoke = new Smoke(this.scene)
    // 绑定点击事件
    this.addClick()
    // 让场景根据鼠标位置进行滚轮缩放
    this.addWheel()
  }
  addWheel() {
    const value = 30
    const body = document.body
    body.onmousewheel = (event) => {
      // 鼠标当前的坐标信息
      const x = (event.clientX / window.innerWidth) * 2 - 1
      const y = -(event.clientY / window.innerHeight) * 2 + 1
      // 创建设备坐标（三维）
      const vector = new THREE.Vector3(x, y, 0.5)
      vector.unproject(this.camera)

      // 做序列化
      vector.sub(this.camera.position).normalize()

      if (event.wheelDelta > 0) {
        this.camera.position.x += vector.x * value
        this.camera.position.y += vector.y * value
        this.camera.position.z += vector.z * value

        this.controls.target.x += vector.x * value
        this.controls.target.y += vector.y * value
        this.controls.target.z += vector.z * value
      } else {
        this.camera.position.x -= vector.x * value
        this.camera.position.y -= vector.y * value
        this.camera.position.z -= vector.z * value

        this.controls.target.x -= vector.x * value
        this.controls.target.y -= vector.y * value
        this.controls.target.z -= vector.z * value
      }
    }
  }
  addClick() {
    let flag = true
    document.onmousedown = () => {
      flag = true

      document.onmousemove = () => {
        flag = false
      }
    }

    document.onmouseup = (event) => {
      if (flag) {
        this.clickEvent(event)
      }
      document.onmousemove = null
    }
  }
  clickEvent(event) {
    // 获取到浏览器坐标
    const x = (event.clientX / window.innerWidth) * 2 - 1
    const y = -(event.clientY / window.innerHeight) * 2 + 1

    // 创建设备坐标（三维）
    const standardVector = new THREE.Vector3(x, y, 0.5)

    // 转化为世界坐标
    const worldVector = standardVector.unproject(this.camera)

    // 做序列化
    const ray = worldVector.sub(this.camera.position).normalize()

    // 如何实现点击选中
    // 创建一个射线发射器，用来发射一条射线
    const raycaster = new THREE.Raycaster(this.camera.position, ray)

    // 返回射线碰撞到的物体
    const intersects = raycaster.intersectObjects(this.scene.children, true)

    let point3d = null
    if (intersects.length) {
      point3d = intersects[0]
    }

    if (point3d) {
      const proportion = 3
      // 开始动画来修改观察点
      const time = 1000

      this.tweenPosition = new TWEEN.Tween(this.camera.position)
        .to(
          {
            x: point3d.point.x * proportion,
            y: point3d.point.y * proportion,
            z: point3d.point.z * proportion
          },
          time
        )
        .start()
      this.tweenRotation = new TWEEN.Tween(this.camera.rotation)
        .to(
          {
            x: this.camera.rotation.x,
            y: this.camera.rotation.y,
            z: this.camera.rotation.z
          },
          time
        )
        .start()
    }
  }
  // 每一帧去调用
  start(delta) {
    for (const key in this.effect) {
      this.effect[key] && this.effect[key].animation()
    }
    // 保留
    if (this.tweenPosition && this.tweenRotation) {
      this.tweenPosition.update()
      this.tweenRotation.update()
    }
    this.time.value += delta

    this.height.value += 0.4
    if (this.height.value > 160) {
      this.height.value = 5
    }
    if (this.top.value > 15 || this.top.value < 0) {
      this.flag = !this.flag
    }
    this.top.value += this.flag ? -0.4 : 0.4
  }
}
